//
// Created on 2025/7/30.
//

#include "BlankScreenDetector.h"
#include <algorithm>
#include <queue>
#include <cmath>
#include <hilog/log.h>
#include "TextLineDetector.h"

#undef LOG_DOMAIN
#undef LOG_TAG
#define LOG_DOMAIN 0x3201
#define LOG_TAG "BlankScreenDetector"

using ColorParams = BlankScreenDetector::AlgorithmParams::ColorParams;
using PixelThresholds = BlankScreenDetector::AlgorithmParams::PixelThresholds;
using RegionParams = BlankScreenDetector::AlgorithmParams::RegionParams;
using SamplingParams = BlankScreenDetector::AlgorithmParams::SamplingParams;
using ThresholdParams = BlankScreenDetector::AlgorithmParams::ThresholdParams;
using ParallelParams = BlankScreenDetector::AlgorithmParams::ParallelParams;

// HSVPixel 实现
HSVPixel::HSVPixel(double hue, double saturation, double value, uint8_t alpha)
    : h(hue), s(saturation), v(value), a(alpha) {}

// Pixel 实现
Pixel::Pixel(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
    : r(red), g(green), b(blue), a(alpha) {}

double Pixel::getLuminance() const {
    return 0.299 * r + 0.587 * g + 0.114 * b;
}

double Pixel::colorDistance(const Pixel& other) const {
    int dr = r - other.r, dg = g - other.g, db = b - other.b;
    return sqrt(dr*dr + dg*dg + db*db);
}

bool Pixel::isBlankPixel(double tolerance) const {
    if (r >= PixelThresholds::WHITE_MIN && g >= PixelThresholds::WHITE_MIN && b >= PixelThresholds::WHITE_MIN) 
        return true;
    if (r <= PixelThresholds::BLACK_MAX && g <= PixelThresholds::BLACK_MAX && b <= PixelThresholds::BLACK_MAX) 
        return true;
    
    int maxDiff = std::max({abs(r-g), abs(g-b), abs(r-b)});
    return maxDiff <= tolerance;
}

bool Pixel::operator==(const Pixel& other) const {
    return r == other.r && g == other.g && b == other.b && a == other.a;
}

HSVPixel Pixel::toHSV() const {
    double rNorm = r / 255.0, gNorm = g / 255.0, bNorm = b / 255.0;
    double cmax = std::max({rNorm, gNorm, bNorm});
    double cmin = std::min({rNorm, gNorm, bNorm});
    double diff = cmax - cmin;

    double h = 0.0, s = (cmax == 0) ? 0 : (diff / cmax) * 100, v = cmax * 100;

    if (diff != 0) {
        if (cmax == rNorm) h = fmod((60 * ((gNorm - bNorm) / diff) + 360), 360.0);
        else if (cmax == gNorm) h = fmod((60 * ((bNorm - rNorm) / diff) + 120), 360.0);
        else h = fmod((60 * ((rNorm - gNorm) / diff) + 240), 360.0);
    }

    return HSVPixel(h, s, v, a);
}

// Rectangle 实现
Rectangle::Rectangle(int x, int y, int w, int h) : x(x), y(y), width(w), height(h) {}
int Rectangle::getArea() const { return width * height; }
bool Rectangle::contains(int px, int py) const {
    return px >= x && px < x + width && py >= y && py < y + height;
}

// BlankRegion & DetectionResult 实现
BlankRegion::BlankRegion() : confidence(0.0), uniformity(0.0), actualPixelCount(0) {}
DetectionResult::DetectionResult() : hasBlankScreen(false), overallBlankRatio(0.0) {
    stats.totalWhiteRegions = stats.totalBlackRegions = stats.totalSolidColorRegions = 0;
    stats.largestRegionArea = 0;
    stats.averageRegionSize = 0.0;
}

// BlankScreenDetector 核心实现
DetectionResult BlankScreenDetector::detect(const uint8_t* pixelData, int width, int height, int bytesPerPixel) {
    startTiming();
    OH_LOG_INFO(LOG_APP, "Starting optimized blank screen detection");
    
    // ===== 输入验证 =====
    DetectionResult invalidResult;
    
    if (!pixelData) {
        invalidResult.summary = "Invalid input: pixelData is null";
        OH_LOG_ERROR(LOG_APP, "Detection failed: pixelData is null");
        return invalidResult;
    }
    
    if (width <= 0 || height <= 0) {
        invalidResult.summary = "Invalid input: width or height is not positive";
        OH_LOG_ERROR(LOG_APP, "Detection failed: width=%{public}d, height=%{public}d", width, height);
        return invalidResult;
    }
    
    if (bytesPerPixel < 3 || bytesPerPixel > 4) {
        invalidResult.summary = "Invalid input: bytesPerPixel must be 3 or 4";
        OH_LOG_ERROR(LOG_APP, "Detection failed: bytesPerPixel=%{public}d", bytesPerPixel);
        return invalidResult;
    }
    
    // 防止整数溢出
    constexpr int64_t MAX_PIXELS = 100000000LL;
    int64_t totalPixels = static_cast<int64_t>(width) * static_cast<int64_t>(height);
    if (totalPixels > MAX_PIXELS) {
        invalidResult.summary = "Invalid input: image too large";
        OH_LOG_ERROR(LOG_APP, "Detection failed: image too large (%{public}ld pixels)", static_cast<long>(totalPixels));
        return invalidResult;
    }
    
    DetectionResult precheckResult = performPrecheckDirect(pixelData, width, height, bytesPerPixel);
    OH_LOG_DEBUG(LOG_APP, "Precheck completed: hasBlankScreen=%{public}s, cost=%{public}lld us", 
                precheckResult.hasBlankScreen ? "true" : "false", getElapsedMicroseconds());
    
    if (precheckResult.hasBlankScreen) {
        return precheckResult;
    }
    
    auto regions = detectRectangularRegionsDirect(pixelData, width, height, bytesPerPixel);
    OH_LOG_DEBUG(LOG_APP, "Detection completed, cost=%{public}lld us", getElapsedMicroseconds());
    
    return generateFinalResult(regions, width, height);
}

DetectionResult BlankScreenDetector::performPrecheckDirect(const uint8_t* pixelData, int width, int height, int bytesPerPixel) {
    DetectionResult result;
    const int step = SamplingParams::PRECHECK_SAMPLE_STEP;
    const SafeBounds bounds(width, height, step);
    
    int totalSamples = 0;
    int colorCounts[4] = {0}; // OTHER, WHITE, BLACK, GRAY
    double totalGradient = 0;
    int gradientSamples = 0;
    
    // 智能选择并行或串行处理
    if (bounds.canUseParallel) {
        // 大数据集：并行处理
        #pragma omp parallel reduction(+:totalSamples,colorCounts[:4],totalGradient,gradientSamples)
        {
            #pragma omp for nowait
            for (int y = 0; y < bounds.safeHeight; y += step) {
                for (int x = 0; x < bounds.safeWidth; x += step) {
                    Pixel p = getPixelDirect(pixelData, x, y, width, bytesPerPixel);
                    totalSamples++;
                    colorCounts[classifyColorFast(p.r, p.g, p.b)]++;
                    
                    // 计算梯度
                    Pixel rightPixel = getPixelDirect(pixelData, x + step, y, width, bytesPerPixel);
                    Pixel downPixel = getPixelDirect(pixelData, x, y + step, width, bytesPerPixel);
                    
                    int gradX = colorDistanceSquared(p.r, p.g, p.b, rightPixel.r, rightPixel.g, rightPixel.b);
                    int gradY = colorDistanceSquared(p.r, p.g, p.b, downPixel.r, downPixel.g, downPixel.b);
                    
                    totalGradient += sqrt(gradX + gradY);
                    gradientSamples++;
                }
            }
        }
    } else {
        // 小数据集：串行处理
        for (int y = 0; y < height; y += step) {
            for (int x = 0; x < width; x += step) {
                Pixel p = getPixelDirect(pixelData, x, y, width, bytesPerPixel);
                totalSamples++;
                colorCounts[classifyColorFast(p.r, p.g, p.b)]++;
                
                if (x + step < width && y + step < height) {
                    Pixel rightPixel = getPixelDirect(pixelData, x + step, y, width, bytesPerPixel);
                    Pixel downPixel = getPixelDirect(pixelData, x, y + step, width, bytesPerPixel);
                    
                    int gradX = colorDistanceSquared(p.r, p.g, p.b, rightPixel.r, rightPixel.g, rightPixel.b);
                    int gradY = colorDistanceSquared(p.r, p.g, p.b, downPixel.r, downPixel.g, downPixel.b);
                    
                    totalGradient += sqrt(gradX + gradY);
                    gradientSamples++;
                }
            }
        }
    }
    
    if (totalSamples == 0) {
        result.summary = "No samples collected during precheck";
        return result;
    }
    
    double whiteRatio = static_cast<double>(colorCounts[1]) / totalSamples;
    double blackRatio = static_cast<double>(colorCounts[2]) / totalSamples;
    double grayRatio = static_cast<double>(colorCounts[3]) / totalSamples;
    double lightSkeletonRatio = whiteRatio + grayRatio;
    double darkSkeletonRatio = blackRatio + grayRatio;
    double avgGradient = (gradientSamples > 0) ? (totalGradient / gradientSamples) : 0.0;
    
    // 只在可能是单色屏幕时才进行文本检测
    bool hasTextContent = false;
    bool hasTextLines = false;
    bool hasTextByFrequency = false;
    if (whiteRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO ||
        blackRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO ||
        grayRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO || 
        lightSkeletonRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO ||
        darkSkeletonRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO) {
        
        hasTextLines = TextLineDetector::hasTextLines(pixelData, width, height, bytesPerPixel);
        hasTextByFrequency = TextLineDetector::hasTextContentByFrequency(pixelData, width, height, bytesPerPixel);
        hasTextContent = hasTextLines || hasTextByFrequency;
    }
    
    OH_LOG_DEBUG(LOG_APP, "Precheck ratios - white: %{public}f, black: %{public}f,  lightSkeletonRatio:"
                          "%{public}f,  darkSkeletonRatio: %{public}f, gray: %{public}f, gradient: %{public}f, hasTextLines: %{public}s, hasTextByFrequency: %{public}s", 
                whiteRatio, blackRatio, lightSkeletonRatio, darkSkeletonRatio, grayRatio, avgGradient,
                hasTextLines ? "true" : "false", hasTextByFrequency ? "true" : "false");
    
    // 判断空白屏幕情况
    // 注意：骨架屏判断应该优先于文本检测，因为骨架屏的占位符元素可能被误判为文本
    bool isLightSkeleton = lightSkeletonRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO &&
                           whiteRatio >= ThresholdParams::PRECHECK_SKELETON_BG_RATIO &&
                           grayRatio >= ThresholdParams::PRECHECK_SKELETON_GRAY_RATIO;
    bool isDarkSkeleton = darkSkeletonRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO &&
                          blackRatio >= ThresholdParams::PRECHECK_SKELETON_BG_RATIO &&
                          grayRatio >= ThresholdParams::PRECHECK_SKELETON_GRAY_RATIO;
    
    if (avgGradient > ThresholdParams::COLOR_GRADIENT_THRESHOLD) {
        result.summary = "Screen has varied content (high gradient)";
    } else if (whiteRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO) {
        // 纯白屏：只有在检测到真正的文本行时才排除
        if (hasTextLines) {
            result.summary = "Text content detected";
        } else {
            result.hasBlankScreen = true;
            result.overallBlankRatio = 1.0;
            result.summary = "Full white screen detected";
            result.blankRegions.push_back(createFullScreenRegion(BlankType::WHITE_SCREEN, 
                                                               Pixel(255, 255, 255), whiteRatio, width, height));
            result.stats.totalWhiteRegions = 1;
        }
    } else if (blackRatio >= ThresholdParams::PRECHECK_DETECTION_RATIO) {
        // 纯黑屏：只有在检测到真正的文本行时才排除
        if (hasTextLines) {
            result.summary = "Text content detected";
        } else {
            result.hasBlankScreen = true;
            result.overallBlankRatio = 1.0;
            result.summary = "Full black screen detected";
            result.blankRegions.push_back(createFullScreenRegion(BlankType::BLACK_SCREEN, 
                                                               Pixel(0, 0, 0), blackRatio, width, height));
            result.stats.totalBlackRegions = 1;
        }
    } else if (isLightSkeleton) {
        // 浅色骨架屏：骨架元素不应该被当作文本
        result.hasBlankScreen = true;
        result.overallBlankRatio = lightSkeletonRatio;
        result.summary = "Light skeleton screen detected";
        result.blankRegions.push_back(createFullScreenRegion(BlankType::SOLID_COLOR, 
                                                           Pixel(245, 245, 245), lightSkeletonRatio, width, height));
        result.stats.totalSolidColorRegions = 1;
    } else if (isDarkSkeleton) {
        // 暗色骨架屏：骨架元素不应该被当作文本
        result.hasBlankScreen = true;
        result.overallBlankRatio = darkSkeletonRatio;
        result.summary = "Dark skeleton screen detected";
        result.blankRegions.push_back(createFullScreenRegion(BlankType::SOLID_COLOR, 
                                                           Pixel(10, 10, 10), darkSkeletonRatio, width, height));
        result.stats.totalSolidColorRegions = 1;
    } else if (hasTextContent) {
        // 其他情况下，如果检测到文本，则不是空白屏
        result.summary = "Text content detected";
    } else {
        result.summary = "Screen has varied content";
    }
    
    return result;
}

std::vector<BlankRegion> BlankScreenDetector::detectRectangularRegionsDirect(const uint8_t* pixelData, int width, int height, int bytesPerPixel) {
    std::vector<BlankRegion> regions;
    const int sampleSize = SamplingParams::REGION_SAMPLE_SIZE;
    
    std::vector<std::vector<bool>> processed(height / sampleSize + 1, 
                                           std::vector<bool>(width / sampleSize + 1, false));

    for (int sy = 0; sy < height; sy += sampleSize) {
        for (int sx = 0; sx < width; sx += sampleSize) {
            int gridY = sy / sampleSize;
            int gridX = sx / sampleSize;

            if (processed[gridY][gridX]) continue;

            Pixel samplePixel = getPixelDirect(pixelData, sx, sy, width, bytesPerPixel);
            if (!samplePixel.isBlankPixel(12.0)) continue;

            BlankRegion region = sampleBasedFloodFillDirect(pixelData, width, height, bytesPerPixel,
                                                           sx, sy, samplePixel, processed, sampleSize);

            if (isAbnormalRectangular(region, width, height)) {
                regions.push_back(region);
                OH_LOG_DEBUG(LOG_APP, "Found region: uniformity=%{public}f, confidence=%{public}f",
                           region.uniformity, region.confidence);
            }
        }
    }

    return regions;
}

BlankRegion BlankScreenDetector::sampleBasedFloodFillDirect(const uint8_t* pixelData, int width, int height, int bytesPerPixel,
                                                           int startX, int startY, const Pixel& targetColor,
                                                           std::vector<std::vector<bool>>& processed, int sampleSize) {
    BlankRegion region;
    region.dominantColor = targetColor;
    region.dominantColorHSV = targetColor.toHSV();

    std::queue<std::pair<int, int>> queue;
    queue.push({startX / sampleSize, startY / sampleSize});

    int minX = startX, maxX = startX, minY = startY, maxY = startY;
    int sampledBlocks = 0;

    while (!queue.empty()) {
        auto [gx, gy] = queue.front();
        queue.pop();

        if (gx < 0 || gx >= (width / sampleSize + 1) || 
            gy < 0 || gy >= (height / sampleSize + 1) || 
            processed[gy][gx]) {
            continue;
        }

        int blockX = gx * sampleSize;
        int blockY = gy * sampleSize;

        if (!isSampleBlockUniformDirect(pixelData, width, height, bytesPerPixel,
                                       blockX, blockY, targetColor, sampleSize)) {
            continue;
        }

        processed[gy][gx] = true;
        sampledBlocks++;

        minX = std::min(minX, blockX);
        maxX = std::max(maxX, blockX + sampleSize - 1);
        minY = std::min(minY, blockY);
        maxY = std::max(maxY, blockY + sampleSize - 1);

        // 4连通扩展
        queue.push({gx-1, gy});
        queue.push({gx+1, gy});
        queue.push({gx, gy-1});
        queue.push({gx, gy+1});
    }

    // 计算区域属性
    region.bounds = Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
    region.actualPixelCount = countActualPixelsDirect(pixelData, width, height, bytesPerPixel,
                                                     region.bounds, targetColor);

    int boundingArea = region.bounds.getArea();
    region.uniformity = boundingArea > 0 ? 
                       static_cast<double>(region.actualPixelCount) / boundingArea : 0.0;
    region.confidence = region.uniformity;

    // 根据亮度判断类型
    double luminance = targetColor.getLuminance();
    if (luminance > PixelThresholds::WHITE_LUMINANCE) {
        region.type = BlankType::WHITE_SCREEN;
        region.description = "White rectangular region";
    } else if (luminance < PixelThresholds::BLACK_LUMINANCE) {
        region.type = BlankType::BLACK_SCREEN;
        region.description = "Black rectangular region";
    } else {
        region.type = BlankType::SOLID_COLOR;
        region.description = "Solid color rectangular region";
    }

    return region;
}

bool BlankScreenDetector::isSampleBlockUniformDirect(const uint8_t* pixelData, int width, int height, int bytesPerPixel,
                                                    int blockX, int blockY, const Pixel& targetColor, int blockSize) const {
    const int step = std::max(1, blockSize / SamplingParams::BLOCK_SAMPLE_STEP_DIVISOR);
    int uniformPixels = 0;
    int totalSamples = 0;

    const int maxX = std::min(blockX + blockSize, width);
    const int maxY = std::min(blockY + blockSize, height);

    for (int y = blockY; y < maxY; y += step) {
        for (int x = blockX; x < maxX; x += step) {
            Pixel pixel = getPixelDirect(pixelData, x, y, width, bytesPerPixel);
            totalSamples++;

            if (colorDistanceSquared(pixel.r, pixel.g, pixel.b, 
                                   targetColor.r, targetColor.g, targetColor.b) < 25) { // 5^2
                uniformPixels++;
            }
        }
    }

    return totalSamples > 0 && 
           (static_cast<double>(uniformPixels) / totalSamples) > RegionParams::FLOOD_FILL_UNIFORMITY_THRESHOLD;
}

int BlankScreenDetector::countActualPixelsDirect(const uint8_t* pixelData, int width, int height, int bytesPerPixel,
                                                const Rectangle& bounds, const Pixel& targetColor) const {
    int count = 0;
    const int step = SamplingParams::PIXEL_COUNT_STEP;
    const int stepSquared = step * step;

    const int maxX = std::min(bounds.x + bounds.width, width);
    const int maxY = std::min(bounds.y + bounds.height, height);

    for (int y = bounds.y; y < maxY; y += step) {
        for (int x = bounds.x; x < maxX; x += step) {
            Pixel pixel = getPixelDirect(pixelData, x, y, width, bytesPerPixel);
            if (colorDistanceSquared(pixel.r, pixel.g, pixel.b,
                                   targetColor.r, targetColor.g, targetColor.b) < ColorParams::UNIFORM_COLOR_DISTANCE_SQUARED) {
                count += stepSquared;
            }
        }
    }

    return std::min(count, bounds.getArea());
}

bool BlankScreenDetector::isAbnormalRectangular(const BlankRegion& region, int width, int height) const {
    // 检查填充率
    if (region.uniformity < RegionParams::BLANK_REGION_MIN_UNIFORMITY) {
        return false;
    }
    
    // 检查最小尺寸要求
    if (region.bounds.width * RegionParams::MIN_REGION_WIDTH_RATIO < width || 
        region.bounds.height * RegionParams::MIN_REGION_HEIGHT_RATIO < height) {
        return false;
    }
    
    // 检查宽高比
    double aspectRatio = static_cast<double>(region.bounds.width) / region.bounds.height;
    if (aspectRatio <= RegionParams::MIN_ASPECT_RATIO || aspectRatio >= RegionParams::MAX_ASPECT_RATIO) {
        return false;
    }
    
    // 检查是否是状态栏/导航栏区域
    const int topMargin = 5;
    bool isFromTop = region.bounds.y <= topMargin;
    bool isFromBottom = (region.bounds.y + region.bounds.height) >= (height - topMargin);
    double widthRatio = static_cast<double>(region.bounds.width) / width;
    double heightRatio = static_cast<double>(region.bounds.height) / height;
    
    if ((isFromTop || isFromBottom) && widthRatio >= 0.85 && heightRatio <= 0.15) {
        return false; // 状态栏/导航栏区域
    }
    
    // 如果均匀性低于文本阈值，需要检查文本内容（简化版本）
    if (region.uniformity < RegionParams::BLANK_REGION_UNIFORMITY_TEXT_THRESHOLD) {
        // 简化：暂时允许通过，避免复杂的文本检测
    }
    
    return true;
}

DetectionResult BlankScreenDetector::generateFinalResult(const std::vector<BlankRegion>& regions, int width, int height) {
    DetectionResult result;
    result.blankRegions = regions;
    const int totalPixels = width * height;

    calculateStatistics(regions, totalPixels, result);
    collectDominantColors(regions, result);

    // 判断是否检测到空白屏
    result.hasBlankScreen = (result.overallBlankRatio > ThresholdParams::OVERALL_BLANK_THRESHOLD) || 
                           (result.stats.largestRegionArea > 
                            static_cast<int>(totalPixels * ThresholdParams::LARGE_REGION_THRESHOLD));

    // 生成摘要
    if (result.hasBlankScreen) {
        result.summary = "Detected " + std::to_string(regions.size()) + 
                        " rectangular blank regions (" + std::to_string(static_cast<int>(result.overallBlankRatio * 100)) + 
                        "% of screen)";
    } else {
        result.summary = "No significant rectangular blank regions detected";
    }
    OH_LOG_DEBUG(LOG_APP, "generateFinalResult completed, cost=%{public}lld us", getElapsedMicroseconds());

    return result;
}

BlankRegion BlankScreenDetector::createFullScreenRegion(BlankType type, const Pixel& color, 
                                                       double confidence, int width, int height) const {
    BlankRegion region;
    region.type = type;
    region.bounds = Rectangle(0, 0, width, height);
    region.dominantColor = color;
    region.dominantColorHSV = color.toHSV();
    region.confidence = confidence;
    region.uniformity = confidence;
    region.actualPixelCount = width * height;
    
    switch (type) {
        case BlankType::WHITE_SCREEN:
            region.description = "Full white screen";
            break;
        case BlankType::BLACK_SCREEN:
            region.description = "Full black screen";
            break;
        case BlankType::SOLID_COLOR:
            region.description = "Full solid color screen";
            break;
        default:
            region.description = "Full screen region";
            break;
    }
    
    return region;
}

void BlankScreenDetector::collectDominantColors(const std::vector<BlankRegion>& regions, 
                                               DetectionResult& result) const {
    std::vector<Pixel> uniqueColors;
    
    for (const auto& region : regions) {
        bool colorExists = false;
        for (const auto& existingColor : uniqueColors) {
            if (colorDistanceSquared(region.dominantColor.r, region.dominantColor.g, region.dominantColor.b,
                                   existingColor.r, existingColor.g, existingColor.b) < ColorParams::UNIFORM_COLOR_DISTANCE_SQUARED) {
                colorExists = true;
                break;
            }
        }
        
        if (!colorExists) {
            uniqueColors.push_back(region.dominantColor);
        }
    }
    
    // 限制主要颜色数量
    if (uniqueColors.size() > ThresholdParams::MAX_DOMINANT_COLORS) {
        uniqueColors.resize(ThresholdParams::MAX_DOMINANT_COLORS);
    }
    
    result.stats.dominantColors = uniqueColors;
    
    // 转换为HSV格式
    result.stats.dominantColorsHSV.clear();
    result.stats.dominantColorsHSV.reserve(uniqueColors.size());
    
    for (const auto& rgbColor : uniqueColors) {
        result.stats.dominantColorsHSV.push_back(rgbColor.toHSV());
    }
}

void BlankScreenDetector::calculateStatistics(const std::vector<BlankRegion>& regions, int totalPixels, 
                                             DetectionResult& result) const {
    int totalBlankPixels = 0;
    result.stats.largestRegionArea = 0;
    
    // 统计各类型区域
    for (const auto& region : regions) {
        totalBlankPixels += region.actualPixelCount;
        result.stats.largestRegionArea = std::max(result.stats.largestRegionArea, region.actualPixelCount);
        
        switch (region.type) {
            case BlankType::WHITE_SCREEN:
                result.stats.totalWhiteRegions++;
                break;
            case BlankType::BLACK_SCREEN:
                result.stats.totalBlackRegions++;
                break;
            case BlankType::SOLID_COLOR:
                result.stats.totalSolidColorRegions++;
                break;
            default:
                break;
        }
    }
    
    // 计算整体统计数据
    result.overallBlankRatio = std::min(1.0, static_cast<double>(totalBlankPixels) / totalPixels);
    result.stats.averageRegionSize = regions.empty() ? 0.0 : 
                                    static_cast<double>(totalBlankPixels) / regions.size();
}
